(component
  (core module $M
    (memory (export "mem") 1)
    (func (export "f1") (result i32)
      (i32.store (i32.const 0) (i32.const 8))
      (i32.store (i32.const 4) (i32.const 1))
      (i32.store8 (i32.const 8) (i32.const 97))
      (i32.const 0)
    )
    (func (export "f2") (result i32)
      (i32.store (i32.const 0) (i32.const 8))
      (i32.store (i32.const 4) (i32.const 14))
      (i64.store (i32.const 8) (i64.const 0xb8_ef_ba_98_e2_83_98_e2))
      (i32.store (i32.const 16) (i32.const 0xe3_b6_c3_8f))
      (i32.store16 (i32.const 20) (i32.const 0x84_83))
      (i32.const 0)
    )
    ;; TODO: so many cases left to test, everyone feel free to fill in...
  )
  (core instance $m (instantiate $M))
  (func (export "f1") (result string) (canon lift (core func $m "f1") (memory $m "mem")))
  (func (export "f2") (result string) (canon lift (core func $m "f2") (memory $m "mem")))
)
(assert_return (invoke "f1") (str.const "a"))
(assert_return (invoke "f2") (str.const "☃☺️öツ"))

(component
  (core module $M
    (memory (export "mem") 1)
    (func (export "f") (result i32)
      (i32.store (i32.const 0) (i32.const 0xdeadbeef))
      (i32.store (i32.const 4) (i32.const 0))
      (i32.const 0)
    )
  )
  (core instance $m (instantiate $M))
  (func (export "f") (result string) (canon lift (core func $m "f") (memory $m "mem")))
)
(assert_trap (invoke "f") "string pointer/length out of bounds of memory")
